package com.wds.service.impl;

import com.wds.common.utils.BeanCopyUtils;
import com.wds.common.utils.JwtUtils;
import com.wds.common.utils.RedisCacheUtils;
import com.wds.domain.JsonResult;
import com.wds.domain.entity.LoginUser;
import com.wds.domain.entity.Menu;
import com.wds.domain.entity.User;
import com.wds.domain.vo.AdminLoginVo;
import com.wds.domain.vo.MenuVo;
import com.wds.domain.vo.RoutersVo;
import com.wds.exception.CustomException;
import com.wds.mapper.UserInfoMapper;
import com.wds.service.AdminAuthenticationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author WDs , wds8.24@outlook.com
 * @version 1.0
 * @since 2022-10-24 15:47
 */
@Service
public class AdminAuthenticationServiceImpl implements AdminAuthenticationService {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisCacheUtils redisCache;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Override
    public JsonResult<Object> login(User user) {
        // 创建认证对象
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
        // 获取认证信息
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);

        if (Objects.isNull(authenticate)) {
            throw new CustomException("用户名或者密码错误");
        }
        // 获取UserID 生成 Token
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        String id = loginUser.getUser().getId().toString();
        String jwtToken = JwtUtils.createJWT(id);
        // 把用户信息存储到redis
        redisCache.setCacheObject("LoginAdmin:" + id, loginUser);
        // 将token 发送到前端

        return JsonResult.ok(new AdminLoginVo(jwtToken));
    }

    /**
     * 退出登录
     */
    @Override
    public JsonResult<Object> logout() {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String key = "LoginAdmin:" + loginUser.getUser().getId();
        redisCache.deleteObject(key);
        return JsonResult.ok("登出成功");
    }

    /**
     * 根据用户id查询权限信息
     */
    @Override
    public List<String> getPermissions(Long id) {
        List<String> perms;
        if (id == 1L) {
//            超级管理员，返回所有权限
            perms = userInfoMapper.queryAllPermissions();
        } else {
            perms = userInfoMapper.queryPermissionsById(id);
        }
        return perms;
    }

    /**
     * 根据用户id查询角色信息
     */
    @Override
    public List<String> getRoles(Long id) {
        return userInfoMapper.queryRoles(id);
    }

    @Override
    public JsonResult<RoutersVo> getRouters(Long id) {
        List<Menu> menus;
        //查询是不是超级管理员
        if (id == 1L) {
            //是， 查询所有菜单数据
            menus = userInfoMapper.queryAllRouters();

        } else {
            //不是，插叙对应的菜单数据
            menus = userInfoMapper.queryRoutersById(id);
        }

//        List<Menu> mMenus = new ArrayList<>();
//        List<Menu> cMenus = new ArrayList<>();
//
//        //封装菜单层级关系
//        for (Menu menu : menus) {
//            if ("M".equals(menu.getMenuType())) {
//                mMenus.add(menu);
//            } else if ("C".equals(menu.getMenuType())) {
//                cMenus.add(menu);
//            }
//        }
//
//        List<MenuVo> menuVoList = mMenus.stream().map(item -> {
//            ArrayList<MenuVo> children = new ArrayList<>();
//            Long parentId = item.getId();
//            for (Menu cMenu : cMenus) {
//                if (parentId.equals(cMenu.getParentId())) {
//                    children.add(BeanCopyUtils.copy(cMenu, MenuVo.class));
//                }
//            }
//            MenuVo menuVo = BeanCopyUtils.copy(item, MenuVo.class);
//            menuVo.setChildren(children);
//            return menuVo;
//        }).collect(Collectors.toList());
//
//        HashMap<String, Object> map = new HashMap<>();
//        map.put("menus", menuVoList);
//        return JsonResult.ok(map);


        List<MenuVo> menuVos = BeanCopyUtils.copyList(menus, MenuVo.class);

        menuVos = builderMenuTree(menuVos, 0L);

        RoutersVo routersVo = new RoutersVo(menuVos);
        return  JsonResult.ok(routersVo);
    }

    /**
     * 传入一个list集合和父节点ID
     * 返回父节点id相匹配的list结合
     * 且自动补全下级节点（递归方式）
     * @param menuVos 目录菜单节点的集合
     * @param parentId 父节点的id
     * @return MenuTree
     */
    private List<MenuVo> builderMenuTree(List<MenuVo> menuVos, Long parentId) {

        return menuVos.stream()
                .filter(menuVo -> menuVo.getParentId().equals(parentId))
                .map(menuVo -> menuVo.setChildren(builderMenuTree(menuVos, menuVo.getId())))
                .collect(Collectors.toList());
    }
}


